/*
 * @Date: 2022-03-02 11:02:15
 * @LastEditors: 春贰
 * @gitee: https://gitee.com/chun22222222
 * @github: https://github.com/chun222
 * @Desc:
 * @LastEditTime: 2023-11-16 15:41:50
 * @FilePath: \go-easy-dashboard\system\middleware\permission.go
 */

package middleware

import (
	"bytes"
	"io/ioutil"
	"net/http" 
	"go-easy-dashboard/system/core/cache"
	"go-easy-dashboard/system/core/db"  
	"go-easy-dashboard/system/core/response"
	"go-easy-dashboard/system/model/DbModel"
	"go-easy-dashboard/system/service/BaseService"
	"go-easy-dashboard/system/util/jwtUtil"
	"go-easy-dashboard/system/util/str"
	"github.com/gin-gonic/gin"
)

type responseWriter struct {
	gin.ResponseWriter
	b *bytes.Buffer
}

//重写 Write([]byte) (int, error) 方法
func (w responseWriter) Write(b []byte) (int, error) {
	//向一个bytes.buffer中写一份数据来为获取body使用
	w.b.Write(b)
	//完成gin.Context.Writer.Write()原有功能
	return w.ResponseWriter.Write(b)
}

func PermissionMid(isEvent ...bool) gin.HandlerFunc {
	// return func(c *gin.Context) {
	// 	c.Next()
	// 	return
	// }
	return func(c *gin.Context) {
		// 请求的PATH
		path := c.Request.URL.Path
		//优先获取缓存
		claims := c.MustGet("claims").(*jwtUtil.CustomClaims)
		Permissions, ok := cache.Get(claims.LoginName)
		if !ok {
			var loginService BaseService.LoginService
			err, user := loginService.GetPerByLoginName(claims.LoginName)
			if err != nil {
				if len(isEvent) > 0 && isEvent[0] {

					response.SSEventSendOnce("error", "permission error", c)
					c.Abort()
				} else {
					c.JSON(http.StatusForbidden, nil)
					c.Abort()
				}
				return
			}
			Permissions = user.Permissions
		}

		// data, err := c.GetRawData()     //这玩意读不到
		body, _ := ioutil.ReadAll(c.Request.Body)

		//写入的
		writer := responseWriter{
			c.Writer,
			bytes.NewBuffer([]byte{}),
		}
		c.Writer = writer

		// //把读过的字节流重新放到body
		c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))

		lenbody := len(body)

		//请求大于1M数据不记录，避免上传大文件还要处理
		if lenbody > 10<<20 {
			c.Next()
			return
		}

		for _, vv := range Permissions.([]DbModel.SysPermission) {
			if vv.Name == path {
				//记录
				if vv.Isrecord == 1 {
					stringRequest := string(body)
					//判断是不是上传文件
					if str.StartsWith(stringRequest, "---") {
						stringRequest = ""
					}
					re := DbModel.SysRecord{
						Uid:      claims.ID,
						Username: claims.UserName,
						Url:      c.Request.URL.Path,
						Desc:     vv.Title,
						Ip:       c.ClientIP(), //c.Request.Header.Get("Origin")
						Request:  stringRequest,
					}
					go record(re) //异步
				}
				c.Next()
				//获取c.Writer所有返回内容 转为字符串
				//响应体 body
				// responseBody := writer.b.String()
				// go hookFinshed(c.Request.URL.Path, c, string(body), responseBody)

				return
			}
		}

		if len(isEvent) > 0 && isEvent[0] {
			response.SSEventSendOnce("error", "permission error", c)
			c.Abort()
		} else {
			c.JSON(http.StatusForbidden, "permission not exsit")
			c.Abort()
		}

	}
}

func record(r DbModel.SysRecord) {
	db.Instance().Create(&r)
}

 